@tool
extends Node

@export var template_name: String = ""

@export var generate: bool = false :
    set(value):
        if value and Engine.is_editor_hint():
            _generate_files()
            generate = false


func _generate_files() -> void:
    if template_name.is_empty():
        push_error("Template name cannot be empty!")
        return
    
    var dir_path = "res://gen"
    _ensure_directory_exists(dir_path)
    
    var generated_name = _to_pascal_case(template_name)
    
    _generate_ability_files(generated_name)
    
    print("Code generation completed!")


func _ensure_directory_exists(path: String) -> void:
    if !DirAccess.dir_exists_absolute(path):
        var dir = DirAccess.open("res://")
        dir.make_dir(path)


func _to_pascal_case(s: String) -> String:
    var parts = s.split("_")
    for i in range(parts.size()):
        parts[i] = parts[i].capitalize()
    return "".join(parts)


func _generate_ability_files(generated_name: String) -> void:
    var base_name = template_name.to_snake_case()
    
    # Generate Ability Asset
    var ability_asset_content = """class_name {0}AbilityAsset
extends GameplayAbilityAsset


func create_spec(owner: AbilitySystemComponent) -> GameplayAbility:
    return {0}Ability.new(self, owner)
""".format([generated_name])
    
    var ability_asset_path = "res://gen/%s_ability_asset.gd" % base_name
    _write_file(ability_asset_path, ability_asset_content)
    
    # Generate Ability
    var ability_content = """class_name {0}Ability
extends GameplayAbility


func _on_owner_set() -> void:
	pass


func _can_apply() -> bool:
	return true


func _on_update(_delta: float) -> void:
	pass


func _create_spec(target: AbilitySystemComponent) -> GameplayAbilitySpec:
	return {0}AbilitySpec.new(self, target)
""".format([generated_name])
    
    var ability_path = "res://gen/%s_ability.gd" % base_name
    _write_file(ability_path, ability_content)
    
    # Generate Ability Spec
    var ability_spec_content = """class_name {0}AbilitySpec
extends GameplayAbilitySpec


func _on_target_set() -> void:
    pass


func _apply() -> void:
    pass


func _on_update(_delta: float) -> void:
    pass


func _end_ability() -> void:
    pass
""".format([generated_name])
    
    var ability_spec_path = "res://gen/%s_ability_spec.gd" % base_name
    _write_file(ability_spec_path, ability_spec_content)


func _write_file(path: String, content: String) -> void:
    var file = FileAccess.open(path, FileAccess.WRITE)
    if file:
        file.store_string(content)
        print("Generated: ", path)
    else:
        push_error("Failed to create file: %s" % path)
